package com.umpay.sp.saas.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import net.sf.json.JSONArray;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFSheet;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.umpay.operation.common.ReqMessage;
import com.umpay.operation.common.ResMessage;
import com.umpay.operation.model.applet.MerchantInfo;
import com.umpay.operation.model.qrConf.QrConf;
import com.umpay.operation.model.saas.RatesConf;
import com.umpay.operation.model.saas.StoreBatch;
import com.umpay.operation.service.applet.StoreInfServiceRemote;
import com.umpay.operation.service.qrConf.remote.QrConfServiceRemote;
import com.umpay.operation.service.saas.RatesServiceRemote;
import com.umpay.operation.service.saas.TStoreBatchDetailServiceRemote;
import com.umpay.operation.service.saas.TStoreBatchServiceRemote;
import com.umpay.sp.common.LoggerManager;
import com.umpay.sp.saas.vo.SetAgentRateCfg;
import com.umpay.sp.web.util.DateUtil;
import com.umpay.sp.web.util.PropertyUtil;
import com.umpay.util.HttpUtil;


/**
 * 立马付批量入网验证Excel字段工具类
 * ================================================================================
 * 		验证批次号是否存在
 * 		验证上传Excel模板
 * 		验证代理商编号是否正确
 * 		验证业务员编号是否正确
 * 		验证收款人四要素（姓名、手机、身份证号、有效期）
 * 		验证店铺简称是否正确
 * 		验证商户类别
 * 		验证客服电话
 * 		验证省
 * 		验证市
 * 		验证区
 * 		验证详细地址
 * 
 * 		验证营业执照号
 * 		验证营业执照名称
 * 		验证营业执照注册日期
 * 		验证主营业务
 * 		验证法人姓名
 * 		验证法人证件号
 * 		验证商户注册详细地址
 * 		验证证书接收邮箱
 * 		验证银行账号
 * 		验证标签一
 * 		验证标签二
 * 		验证立马付微信、支付宝费率
 * 		验证固码1
 * 		验证固码2
 * 		验证固码3
 * 		验证固码4
 * 
 * 		验证店铺简称是否重名
 * ================================================================================
 * @author ChenFuLong
 *
 */
public class ValidateUtil {
	

	public final static Logger logger = LoggerManager.getBusiLogger();
	
	/**
	 * 日期正则：yyyy-MM-dd
	 */
	public final static Pattern DA_PATTERN = Pattern.compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\-\\s]?((((0?" +"[13578])|(1[02]))[\\-\\-\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))" +"|(((0?[469])|(11))[\\-\\-\\s]?((0?[1-9])|([1-2][0-9])|(30)))|" +"(0?2[\\-\\-\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][12" +"35679])|([13579][01345789]))[\\-\\-\\s]?((((0?[13578])|(1[02]))" +"[\\-\\-\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))" +"[\\-\\-\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\-\\s]?((0?[" +"1-9])|(1[0-9])|(2[0-8]))))))");

	/**
	 * 手机号正则：1开头，3-9，任意9位数
	 */
	public final static String MOBILE_REGEX = "1[3-9][0-9]{9}";
	
	/**
	 * 座机号正则：区号-7位或8位
	 */
	public final static Pattern FIXED_PATTERN = Pattern.compile("^0\\d{2,3}-\\d{7,8}$");  
	
	/**
	 * 400电话正则
	 */
	public final static Pattern S_PATTERN = Pattern.compile("^400[0-9]{7}");
	
	/**
	 * 商户类别（经营类目）正则：00/00/00
	 */
	public final static String MER_REGEX = "[0-9]{2}/[0-9]{2}/[0-9]{2}";
	
	/**
	 * 数字正则（用于序列号）
	 */
	public final static Pattern NUM_PATTERN0 = Pattern.compile("^[0-9]*$");
	
	/**
	 * 4位数字正则（用于省市区）
	 */
	public final static Pattern NUM_PATTERN = Pattern.compile("\\d{4}");
	
	/**
	 * 营业执照编号正则
	 */
	public final static Pattern NUM2_PATTERN = Pattern.compile("\\d{10,30}");
	
	/**
	 * 8位数字正则（用于固码）
	 */
	public final static Pattern NUM3_PATTERN = Pattern.compile("\\d{8}");
	
	/**
	 * 12位数字正则（用于批次号）
	 */
	public final static Pattern NUM4_PATTERN = Pattern.compile("\\d{12}");
	
	/**
	 * 邮箱地址正则
	 */
	public final static String EMAIL_REGEX = "\\w+(\\.\\w)*@\\w+(\\.\\w{2,3}){1,3}";
	
	public final static String AGENT_CRM_QUERYAGENTMANAGER = PropertyUtil.getStrValue("spEnterpriseWeb_config.properties","agent.crm.queryAgentManager", "");
	public final static String ID_AUTH = PropertyUtil.getStrValue("spEnterpriseWeb_config.properties","id.auth", "");
	public final static String AGENTPROFITURL = PropertyUtil.getStrValue("spEnterpriseWeb_config.properties","agentProfitUrl", "");
	public final static String JQMERID = PropertyUtil.getStrValue("spEnterpriseWeb_config.properties","jQmerId", "");
	public final static String AGENTPROFITTYPE = PropertyUtil.getStrValue("spEnterpriseWeb_config.properties","agentProfitType", "");
	
	public final static StoreInfServiceRemote storeInfServiceRemote = DubboInvokerUtil.getInvoker(StoreInfServiceRemote.class);
	public final static RatesServiceRemote ratesServiceRemote = DubboInvokerUtil.getInvoker(RatesServiceRemote.class);
	
	public final static TStoreBatchServiceRemote tStoreBatchServiceRemote = DubboInvokerUtil.getInvoker(TStoreBatchServiceRemote.class);
	public final static TStoreBatchDetailServiceRemote tStoreBatchDetailServiceRemote = DubboInvokerUtil.getInvoker(TStoreBatchDetailServiceRemote.class);
	public final static QrConfServiceRemote qrConfServiceRemote = DubboInvokerUtil.getInvoker(QrConfServiceRemote.class);
	
	/**
	 * 验证批次号是否存在
	 * @param agentId代理商编号
	 * @param number批次号
	 * @return
	 */
	public static Map<String, String> batchNo(String agentId, String number){
		Map<String, String> map = new HashMap<String, String>();
		String batchNo = agentId + "_" + number;
		logger.info("【开始验证批次号文件名规则】" + batchNo);//上传的EXCEL名称命名为201702020001（兼容2003-2007格式）这样年月日+四位数字
		if (!NUM4_PATTERN.matcher(number).matches()) {
			map.put("retCode", "0005");
			map.put("retMsg", "文件命名错误");
			return map;
		}
		logger.info("【开始验证批次号是否存在】" + batchNo);
		com.umpay.operation.common.ReqMessage req = ReqMessageUtil.makeOpReq();
		com.umpay.operation.common.ResMessage res = null;
		req.put("batchNo",batchNo);
		try {
			logger.info("【查询批次信息】入参" + req);
			res = tStoreBatchServiceRemote.queryStoreBatchList(req);
			logger.info("【查询批次信息】出参" + res);
		} catch (Exception e) {
			logger.error("【查询批次信息】异常", e);
			map.put("retCode", "1111");
			map.put("retMsg", "获取批次号失败，请重试");
			return map;
		}
		if (!"0000".equals(res.getRetCode())) {
			map.put("retCode", "1111");
			map.put("retMsg", "获取批次号失败，请重试");
			return map;
		}
		List<StoreBatch> storeBatchs = (List<StoreBatch>) res.getResMap().get("storeBatchList");
		if (null != storeBatchs && storeBatchs.size() > 0) {
			map.put("retCode", "0006");
			map.put("retMsg", "已存在相同批次号请修改名称后上传");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证上传Excel模板
	 * @param sheet
	 * @return
	 */
	public static Map<String, String> template(HSSFSheet sheet){
		logger.info("【验证上传Excel模板】开始");
		Map<String, String> map = new HashMap<String, String>();
		Map<Integer, String> field = initMap();
		//【1】验证模板第一行
		for (int i = 0; i < field.size(); i++) {
			if (!field.get(i).equals(String.valueOf(sheet.getRow(0).getCell(i)))) {
				logger.info("ERROR = Excel字段：【" + sheet.getRow(0).getCell(i) + "】顺序或名称不正确");
				map.put("retCode", "0001");
				return map;
			}
		}
		//【2】验证序列号以及是否有整行为空的数据
		for (int i = 1; i <= sheet.getLastRowNum(); i++) {
			HSSFCell seqCell = sheet.getRow(i).getCell(0);
			if (null == seqCell) {
				logger.info("ERROR = 必填信息为空");
				map.put("retCode", "0004");
				return map;
			}
			seqCell.setCellType(seqCell.CELL_TYPE_STRING);
			String seqNum = String.valueOf(sheet.getRow(i).getCell(0));
			if (StringUtils.isBlank(seqNum) || "null".equals(seqNum)) {
				logger.info("ERROR = 序列号为空");
				map.put("retCode", "0002");
				return map;
			}
			if (!NUM_PATTERN0.matcher(seqNum).matches()) {
				logger.info("ERROR = 序列号错误");
				map.put("retCode", "0002");
				return map;
			}
			for (int j = 1; j < 12; j++) {
				String text = String.valueOf(sheet.getRow(i).getCell(j)).trim();
				if (StringUtils.isBlank(text) || "null".equals(text)) {
					logger.info("ERROR = 必填信息为空");
					map.put("retCode", "0004");
					return map;
				}
			}
		}
		map.put("retCode", "0000");
		return map;
	}
	//初始化Map中的值（Excel模板）
	public static Map<Integer, String> initMap(){
		Map<Integer, String> map= new HashMap<Integer, String>();
		map.put(0, "序列号");
		map.put(1, "代理商编号");
		map.put(2, "申请商户类别");
		map.put(3, "收款人姓名");
		map.put(4, "收款人身份证号码");
		map.put(5, "证件有效期");
		map.put(6, "收款人手机号");
		map.put(7, "商户简称（用于前端显示）");
		map.put(8, "商户类别（经营类目）");
		map.put(9, "客服电话");
		map.put(10, "省");
		map.put(11, "市");
		map.put(12, "区/县");
		map.put(13, "详细地址");
		map.put(14, "营业执照号");
		map.put(15, "营业执照名称");
		map.put(16, "营业执照注册日期");
		map.put(17, "主营业务");
		map.put(18, "法人姓名");
		map.put(19, "法人证件号");
		map.put(20, "法人证件号有效期");
		map.put(21, "商户注册详细地址");
		map.put(22, "证书接收邮箱");
		map.put(23, "银行账号");
		map.put(24, "银行预留手机号");
		map.put(25, "标签一");
		map.put(26, "标签二");
		map.put(27, "业务员");
		map.put(28, "立马付微信费率(%)");
		map.put(29, "立马付支付宝费率(%)");
		map.put(30, "固码1");
		map.put(31, "固码2");
		map.put(32, "固码3");
		map.put(33, "固码4");
		return map;
	}
	
	/**
	 * 验证代理商编号是否正确
	 * @param agentId代理商编号
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, String> agentId(String agentId) {
		Map<String, String> map = new HashMap<String, String>();
		logger.info("【开始验证代理商编号】" + agentId);
		if (StringUtils.isBlank(agentId) || "null".equals(agentId)) {
			logger.info("ERROR = 代理商编号不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "代理商编号不能为空");
			return map;
		}
		if (agentId.length() != 10) {
			logger.info("ERROR = 代理商编号错误，位数不等于10");
			map.put("retCode", "1111");
			map.put("retMsg", "代理商编号不存在");
			return map;
		}
		Map<String, Object> req = ReqMessageUtil.makeCrmMap();
		Map<String, Object> res = new HashMap<String, Object>();
		req.put("rpid", "saasPlat" + System.currentTimeMillis());
		req.put("agentId", agentId);
		req.put("userName", "admin");
		try {
			XStream xstream = new XStream(new DomDriver());
			logger.info("【查询代理商管理员信息】入参：" + req + "【请求路径】" + AGENT_CRM_QUERYAGENTMANAGER);
			res = (Map<String, Object>) HttpUtils.getResObjPost(AGENT_CRM_QUERYAGENTMANAGER, xstream, req);
			logger.info("【查询代理商管理员信息】出参：" + res);
		} catch (Exception e) {
			logger.error("【查询代理商管理员信息】异常", e);
			map.put("retCode", "1111");
			map.put("retMsg", "代理商编号错误");
			return map;
		}
		if(!"0000".equals(res.get("retCode"))){
			logger.info("ERROR = 代理商编号错误");
			map.put("retCode", "1111");
			map.put("retMsg", "代理商编号不存在");
			return map;
		}
		List<Map<String,String>> list = (List<Map<String,String>>)res.get("agentManagerList");
		if (list.size() == 0) {
			logger.info("ERROR = 代理商编号不存在");
			map.put("retCode", "1111");
			map.put("retMsg", "代理商编号不存在");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证业务员编号是否正确
	 * @param agentId代理商编号
	 * @param salesmanId业务员编号
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, String> salesmanId(String agentId, String salesmanId){
		Map<String, String> map = new HashMap<String, String>();
		logger.info("【开始验证业务员编号】" + salesmanId);
		Map<String, Object> req = ReqMessageUtil.makeCrmMap();
		Map<String, Object> res = null;
		req.put("agentId", agentId);
		req.put("userName", salesmanId);
		try {
			XStream xstream = new XStream(new DomDriver());
			logger.info("【查询代理商管理员信息】入参：" + req + "【请求路径】" + AGENT_CRM_QUERYAGENTMANAGER);
			res = (Map<String, Object>) HttpUtils.getResObjPost(AGENT_CRM_QUERYAGENTMANAGER, xstream, req);
			logger.info("【查询代理商管理员信息】出参：" + res);
		} catch (Exception e) {
			logger.error("【查询代理商管理员信息】异常", e);
			map.put("retCode", "1111");
			map.put("retMsg", "业务员编号错误");
			return map;
		}
		if(!"0000".equals(res.get("retCode"))){
			logger.info("ERROR = 业务员编号错误");
			map.put("retCode", "1111");
			map.put("retMsg", "业务员编号不存在");
			return map;
		}
		List<Map<String,String>> list = (List<Map<String,String>>)res.get("agentManagerList");
		if (list.size() == 0) {
			logger.info("ERROR = 业务员编号不存在");
			map.put("retCode", "1111");
			map.put("retMsg", "业务员编号不存在");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证收款人四要素
	 * @param payeeName收款人姓名
	 * @param payeeIdentity收款人身份证号（明文）
	 * @param payeeInidcardValid收款人身份证有效期
	 * @param payeeMobile收款人手机号
	 * @return defultStore默认店铺、merId主商户号
	 */
	public static Map<String, String> identityInfo(String payeeName, String payeeInidcard, String payeeInidcardValid, String payeeMobileId){
		logger.info("【开始验证收款人四要素】" + "姓名：" + payeeName + "身份证号：" + payeeInidcard + "有效期：" + payeeInidcardValid + "手机号：" + payeeMobileId);
		Map<String, String> map = new HashMap<String, String>();
		String defultStore = "0";	//默认店铺	0默认店铺；1非默认店铺
		String merId = "";	//生成主商户号，即主商户店铺编号
		if (StringUtils.isBlank(payeeInidcardValid) || "null".equals(payeeInidcardValid)) {
			logger.info("ERROR = 证件有效期不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "证件有效期不能为空");
			return map;
		}
		if (!DA_PATTERN.matcher(payeeInidcardValid).matches()) {
			logger.info("ERROR = 证件有效期格式错误");
			map.put("retCode", "1111");
			map.put("retMsg", "证件有效期格式错误");
			return map;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String now = sdf.format(new Date());
		if (!now.equals(payeeInidcardValid)) {
			if (date(payeeInidcardValid)) {
				map.put("retCode", "1111");
				map.put("retMsg", "证件有效期不能小于今天");
				return map;
			}
		}
		if (!payeeMobileId.matches(MOBILE_REGEX)) {
			logger.info("ERROR = 收款人手机号格式错误");
			map.put("retCode", "1111");
			map.put("retMsg", "收款人手机号格式错误");
			return map;
		}
		
		if (!IdcardValidator.isValidatedAllIdcard(payeeInidcard)) {
			logger.info("ERROR = 工具类校验，收款人身份证号错误");
			map.put("retCode", "1111");
			map.put("retMsg", "收款人身份证号错误");
			return map;
		}
		
		//【1】查询店铺表，检查此身份证号是否存在
		ReqMessage req = ReqMessageUtil.makeOpReq();
		ResMessage res = null;
		req.put("payeeInidcard", DesIDUtil.encID(payeeInidcard));
		req.put("isDel","0"); //是否删除：0未删除；  1已删除
		try {
			logger.info("【根据身份证号查询店铺列表】入参" + req);
			res = storeInfServiceRemote.getStoreInfListForBatch(req);
			logger.info("【根据身份证号查询店铺列表】出参" + res);
		} catch (Exception e) {
			logger.error("【根据身份证号查询店铺列表】异常", e);
		}
		if(null != res){
			Integer totalSize = (Integer) res.getResMap().get("totalSize");
			if (res.getRetCode().equals("0000") && totalSize > 0) {	//判断返回码是否为0000且totalSize>0，说明已经开通过商户
				List<MerchantInfo> merchantInfo = (List<MerchantInfo>) res.getResMap().get("storeInfList");
				for (MerchantInfo storeInf : merchantInfo) {
					if (!payeeName.equals(storeInf.getPayeeName()) || !payeeMobileId.equals(storeInf.getPayeeMobileId())) {
						map.put("retCode", "1111");
						map.put("retMsg", "收款人身份信息不一致");
						logger.info("ERROR = 收款人信息与店铺表信息不一致");
						return map;
					}
					if (storeInf.getDefultStore().equals("0") || storeInf.getDefultStore() == "0") {	//判断是否有默认店铺
						defultStore = "1";
					}
					if(null != storeInf.getMerId() && !"".equals(storeInf.getMerId())){	//获取主商户号
						merId = storeInf.getMerId();
					}else {
						merId = storeInf.getStoreId();
					}
				}
				map.put("retCode", "0000");
				map.put("defultStore", defultStore);
				map.put("merId", merId);
				return map;
			}
		}
/*		
		//【2】查询批次明细表，检查此身份证号是否存在
		try {
			ReqMessage req1 = ReqMessageUtil.makeOpReq();
			req1.put("payeeInidcard", DesIDUtil.encID(payeeInidcard));
			req1.put("delFlag","0");// 是否删除 CHAR(1)  0:未删除；1:已删除
			logger.info("【根据身份证号查询批次明细店铺列表】入参" + req1);
			res = tStoreBatchDetailServiceRemote.queryBatchDetailList(req1);
			logger.info("【根据身份证号查询批次明细店铺列表】出参" + res);
		} catch (Exception e) {
			logger.error("【根据身份证号查询批次明细店铺列表】异常", e);
		}
		if(null != res){
			List<StoreBatchDetail> storeBatchDetailList = (List<StoreBatchDetail>) res.getResMap().get("storeBatchDetailList");
			if (res.getRetCode().equals("0000") && storeBatchDetailList.size() > 0) {	//判断返回码是否为0000且storeBatchDetailList>0，说明有此信息
				for (StoreBatchDetail storeBatchDetail : storeBatchDetailList) {
					if (!payeeName.equals(storeBatchDetail.getPayeeName()) || !payeeMobileId.equals(storeBatchDetail.getPayeeMobileId())) {
						map.put("retCode", "1111");
						map.put("retMsg", "收款人身份信息不一致");
						logger.info("ERROR = 收款人信息与批次详情表数据不一致");
						return map;
					}
				}
				map.put("retCode", "0000");
				map.put("defultStore", defultStore);
				return map;
			}
		}
*/		
		//【3】调用国政通，检查身份信息
		Map<String, Object> reqAuth = ReqMessageUtil.makeCrmMap();
		Map<String, Object> resAuth = null;
		reqAuth.put("reqDate", DateUtil.getSystemDate("yyyyMMdd"));
		reqAuth.put("reqTime", DateUtil.getSystemDate("HHmmss"));
		reqAuth.put("merId",JQMERID);
		reqAuth.put("busiMerId",JQMERID);	//业务商户号（文档中写的是：25998）
		reqAuth.put("productId","P15R00RZ");	//产品号
		reqAuth.put("authMode","3");	//验证方式
		reqAuth.put("accountName", payeeName);	//姓名
		reqAuth.put("bankIdentityCode",DesIDUtil.encID(payeeInidcard));	//身份证号（DES加密码）
		try {
			logger.info("【调用国政通身份认证】入参" + reqAuth + "【请求地址】" + ID_AUTH);
			resAuth = HttpUtil.httpPostForm2Xml(ID_AUTH, reqAuth, "utf-8");
			logger.info("【调用国政通身份认证】出参" + resAuth);
		} catch (Exception e) {
			logger.error("【调用国政通身份认证】异常", e);
			map.put("retCode", "1111");
			map.put("defultStore", defultStore);
			map.put("retMsg", "身份证认证失败");
			return map;
		}
		if (!"0000".equals(resAuth.get("retCode"))) {	//国政通身份认证不匹配
			map.put("retCode", "1111");
			map.put("defultStore", defultStore);
			map.put("retMsg", "身份证认证失败");
			logger.info("ERROR = 国政通校验身份信息不匹配");
			return map;
		}
		map.put("retCode", "0000");
		map.put("defultStore", defultStore);
		return map;
	}
	
	/**
	 * 验证店铺简称是否正确
	 * @param storeShortName店铺简称
	 * @return
	 */
	public static Map<String, String> storeShortName(String storeShortName){
		logger.info("【开始验证店铺简称是否正确】" + storeShortName);
		Map<String, String> map = new HashMap<String, String>();
		if(StringUtils.isBlank(storeShortName) || "null".equals(storeShortName)){
			logger.info("ERROR = 店铺简称不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "店铺简称不能为空");
			return map;
		}
		if (storeShortName.length() > 16) {
			logger.info("ERROR = 店铺简称不能超过16个汉字");
			map.put("retCode", "1111");
			map.put("retMsg", "店铺简称不能超过16个汉字");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证商户类别（经营类目）
	 * @param storeCategory商户类别
	 * @return
	 */
	public static Map<String, String> storeCategory(String storeCategory){
		logger.info("【开始验证商户类别（经营类目）】" + storeCategory);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isBlank(storeCategory) || "null".equals(storeCategory)) {
			logger.info("ERROR = 商户类别（经营类目）不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "商户类别不能为空");
			return map;
		}
		
		if(!storeCategory.matches(MER_REGEX)){
			logger.info("ERROR = 商户类别（经营类目）填写错误");
			map.put("retCode", "1111");
			map.put("retMsg", "商户类别填写错误");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证客服电话
	 * @param phone客服电话
	 * @return
	 */
	public static Map<String, String> phone(String phone){
		logger.info("【开始验证客服电话】" + phone);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isBlank(phone) || "null".equals(phone)) {
			logger.info("ERROR = 客服电话不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "客服电话不能为空");
			return map;
		}
		if(!phone.matches(MOBILE_REGEX)){	//手机号
			if(!FIXED_PATTERN.matcher(phone).matches()){	//座机
				if (!S_PATTERN.matcher(phone).matches()) {	//400
					logger.info("ERROR = 客服电话格式错误");
					map.put("retCode", "1111");
					map.put("retMsg", "客服电话格式错误");
					return map;
				}
			}
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证省
	 * @param storeAddrProv省
	 * @return
	 */
	public static Map<String, String> storeAddrProv (String storeAddrProv){
		logger.info("【开始验证省市区】" + "省：" + storeAddrProv);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isBlank(storeAddrProv) || "null".equals(storeAddrProv)) {
			logger.info("ERROR = 省不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "省不能为空");
			return map;
		}
		if (!NUM_PATTERN.matcher(storeAddrProv).matches()) {
			logger.info("ERROR = 省格式错误");
			map.put("retCode", "1111");
			map.put("retMsg", "省格式错误");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证市
	 * @param storeAddrCity市
	 * @return
	 */
	public static Map<String, String> storeAddrCity (String storeAddrCity){
		logger.info("【开始验证省市区】" + "市：" + storeAddrCity);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isBlank(storeAddrCity) || "null".equals(storeAddrCity)) {
			logger.info("ERROR = 市不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "市不能为空");
			return map;
		}
		if (!NUM_PATTERN.matcher(storeAddrCity).matches()) {
			logger.info("ERROR = 市格式错误");
			map.put("retCode", "1111");
			map.put("retMsg", "市格式错误");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证区
	 * @param storeAddrArea区
	 * @return
	 */
	public static Map<String, String> storeAddrArea (String storeAddrArea){
		logger.info("【开始验证省市区】" + "区：" + storeAddrArea);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(storeAddrArea) && !"null".equals(storeAddrArea)) {
			if (!NUM_PATTERN.matcher(storeAddrArea).matches()) {
				logger.info("ERROR = 区/县格式错误");
				map.put("retCode", "1111");
				map.put("retMsg", "区/县格式错误");
				return map;
			}
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证详细地址
	 * @param storeFullAddress详细地址
	 * @return
	 */
	public static Map<String, String> storeFullAddress(String storeFullAddr){
		logger.info("【开始验证详细地址】" + storeFullAddr);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(storeFullAddr) && !"null".equals(storeFullAddr)) {
			if (storeFullAddr.length() > 100) {
				logger.info("ERROR = 详细地址不能超过100个汉字");
				map.put("retCode", "1111");
				map.put("retMsg", "详细地址不能超过100个汉字");
				return map;
			}
		}else {
			logger.info("ERROR = 详细地址不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "详细地址不能为空");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证营业执照号
	 * @param licenseNo营业执照号
	 * @return
	 */
	public static Map<String, String> licenseNo(String licenseNo){
		logger.info("【开始验证营业执照号】" + licenseNo);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(licenseNo) && !"null".equals(licenseNo)) {
			if (!NUM2_PATTERN.matcher(licenseNo).matches()) {
				logger.info("ERROR = 营业执照号格式错误");
				map.put("retCode", "1111");
				map.put("retMsg", "营业执照号格式错误");
				return map;
			}
		}else {
			logger.info("ERROR = 营业执照号不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "营业执照号不能为空");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证营业执照名称
	 * @param storeName营业执照名称
	 * @return
	 */
	public static Map<String, String> storeName(String storeFullName){
		logger.info("【开始验证营业执照名称】" + storeFullName);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(storeFullName) && !"null".equals(storeFullName)) {
			if (storeFullName.length() > 64) {
				logger.info("ERROR = 营业执照名称不能超过64个汉字");
				map.put("retCode", "1111");
				map.put("retMsg", "营业执照名称不能超过64个汉字");
				return map;
			}
		}else {
			logger.info("ERROR = 营业执照名称不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "营业执照名称不能为空");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证营业执照注册日期
	 * @param registerDate营业执照注册日期
	 * @return
	 */
	public static Map<String, String> registerDate(String registerDate){
		logger.info("【开始验证营业执照注册日期】" + registerDate);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(registerDate) && !"null".equals(registerDate)) {
			if (!DA_PATTERN.matcher(registerDate).matches()) {
				logger.info("ERROR = 营业执照注册日期格式错误");
				map.put("retCode", "1111");
				map.put("retMsg", "营业执照注册日期格式错误");
				return map;
			}
			if (!date(registerDate)) {
				map.put("retCode", "1111");
				map.put("retMsg", "营业执照注册日期不能大于今天");
				return map;
			}
		}else {
			logger.info("ERROR = 营业执照注册日期不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "营业执照注册日期不能为空");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	public static boolean date(String date){
		Date now = new Date();
		Date past = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			past = sdf.parse(date);
			if (past.before(now)) {
				return true;
			}
		} catch (ParseException e) {
			return true;
		}
		return false;
	}
	
	/**
	 * 验证主营业务
	 * @param storeKind主营业务
	 * @return
	 */
	public static Map<String, String> storeKind(String mainBusiness){
		logger.info("【开始验证主营业务】" + mainBusiness);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(mainBusiness) && !"null".equals(mainBusiness)) {
			if (mainBusiness.length() > 128) {
				logger.info("ERROR = 主营业务不能超过128个汉字");
				map.put("retCode", "1111");
				map.put("retMsg", "主营业务不能超过128个汉字");
				return map;
			}
		}else {
			logger.info("ERROR = 主营业务不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "主营业务不能为空");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证法人姓名
	 * @param storeMan法人姓名
	 * @return
	 */
	public static Map<String, String> storeMan(String storeMan){
		logger.info("【开始验证法人姓名】" + storeMan);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(storeMan) && !"null".equals(storeMan)) {
			if (storeMan.length() > 32) {
				logger.info("ERROR = 法人姓名不能超过32个汉字");
				map.put("retCode", "1111");
				map.put("retMsg", "法人姓名不能超过32个汉字");
				return map;
			}
		}else {
			logger.info("ERROR = 法人姓名不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "法人姓名不能为空");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证法人证件号
	 * @param storeMan法人姓名
	 * @param storeManIdentity法人证件号
	 * @param storeManIdentityValid法人证件有效期
	 * @return
	 */
	public static Map<String, String> storeManIdentity(String storeMan, String storeManIdentity, String storeManIdentityValid){
		logger.info("【开始验证法人证件号】" + storeManIdentity);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isBlank(storeManIdentity) || "null".equals(storeManIdentity)) {
			logger.info("ERROR = 法人证件号不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "法人证件号不能为空");
			return map;
		}
		if (!IdcardValidator.isValidatedAllIdcard(storeManIdentity)) {
			logger.info("ERROR = 工具类校验，法人证件号错误");
			map.put("retCode", "1111");
			map.put("retMsg", "法人证件号错误");
			return map;
		}
		if (StringUtils.isBlank(storeManIdentityValid) || "null".equals(storeManIdentityValid)) {
			logger.info("ERROR = 法人证件有效期不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "证件有效期不能为空");
			return map;
		}
		if (!DA_PATTERN.matcher(storeManIdentityValid).matches()) {
			logger.info("ERROR = 法人证件有效期格式错误");
			map.put("retCode", "1111");
			map.put("retMsg", "法人证件有效期格式错误");
			return map;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String now = sdf.format(new Date());
		if (!now.equals(storeManIdentityValid)) {
			if (date(storeManIdentityValid)) {
				map.put("retCode", "1111");
				map.put("retMsg", "法人证件有效期不能小于今天");
				return map;
			}
		}
		
		//【1】查询店铺表，检查此法人证件号是否存在
		ReqMessage req = ReqMessageUtil.makeOpReq();
		ResMessage res = null;
		req.put("categoryManCardno", DesIDUtil.encID(storeManIdentity));
		req.put("isDel","0"); //是否删除：0未删除；  1已删除
		try {
			logger.info("【根据法人证件号查询店铺列表】入参" + req);
			res = storeInfServiceRemote.getStoreInfList(req);
			logger.info("【根据法人证件号查询店铺列表】出参" + res);
		} catch (Exception e) {
			logger.error("【根据法人证件号查询店铺列表】异常", e);
		}
		if(null != res){
			Integer totalSize = (Integer) res.getResMap().get("totalSize");
			if (res.getRetCode().equals("0000") && totalSize > 0) {	//判断返回码是否为0000且totalSize>0，说明有
				List<MerchantInfo> merchantInfo = (List<MerchantInfo>) res.getResMap().get("storeInfList");
				for (MerchantInfo storeInf : merchantInfo) {
					if (!storeMan.equals(storeInf.getCategoryManName())) {
						map.put("retCode", "1111");
						map.put("retMsg", "法人证件信息不一致");
						logger.info("ERROR = 法人证件号信息与店铺表信息不一致");
						return map;
					}
				}
				map.put("retCode", "0000");
				return map;
			}
		}
/*		
		//【2】查询批次明细表，检查此身份证号是否存在
		try {
			ReqMessage req1 = ReqMessageUtil.makeOpReq();
			req1.put("categoryManCardno", DesIDUtil.encID(storeManIdentity));
			req1.put("delFlag","0");// 是否删除 CHAR(1)  0:未删除；1:已删除
			logger.info("【根据法人证件号查询批次明细店铺列表】入参" + req1);
			res = tStoreBatchDetailServiceRemote.queryBatchDetailList(req1);
			logger.info("【根据法人证件号查询批次明细店铺列表】出参" + res);
		} catch (Exception e) {
			logger.error("【根据法人证件号查询批次明细店铺列表】异常", e);
		}
		if(null != res){
			Integer totalSize = (Integer) res.getResMap().get("storeBatchDetailCount");
			if (res.getRetCode().equals("0000") && totalSize > 0) {	//判断返回码是否为0000且totalSize>0，说明有此信息
				List<StoreBatchDetail> storeBatchDetails = (List<StoreBatchDetail>) res.getResMap().get("storeBatchDetailList");
				for (StoreBatchDetail storeBatchDetail : storeBatchDetails) {
					if (!storeMan.equals(storeBatchDetail.getCategoryManName())) {
						map.put("retCode", "1111");
						map.put("retMsg", "法人证件信息不一致");
						logger.info("ERROR = 法人证件号信息与店铺表信息不一致");
						return map;
					}
				}
				map.put("retCode", "0000");
				return map;
			}
		}
*/		
		//【3】调用国政通，检查身份信息
		Map<String, Object> reqAuth = ReqMessageUtil.makeCrmMap();
		Map<String, Object> resAuth = null;
		reqAuth.put("reqDate", DateUtil.getSystemDate("yyyyMMdd"));
		reqAuth.put("reqTime", DateUtil.getSystemDate("HHmmss"));
		reqAuth.put("merId",JQMERID);
		reqAuth.put("busiMerId",JQMERID);	//业务商户号（文档中写的是：25998）
		reqAuth.put("productId","P15R00RZ");	//产品号
		reqAuth.put("authMode","3");	//验证方式
		reqAuth.put("accountName", storeMan);	//姓名
		reqAuth.put("bankIdentityCode",DesIDUtil.encID(storeManIdentity));	//身份证号（DES加密码）
		try {
			logger.info("【调用国政通身份认证】入参" + reqAuth);
			resAuth = HttpUtil.httpPostForm2Xml(ID_AUTH, reqAuth, "utf-8");
			logger.info("【调用国政通身份认证】出参" + resAuth);
		} catch (Exception e) {
			logger.error("【调用国政通身份认证】异常", e);
			map.put("retCode", "1111");
			map.put("retMsg", "法人证件信息认证失败");
			return map;
		}
		if (!"0000".equals(resAuth.get("retCode"))) {	//国政通身份认证不匹配
			map.put("retCode", "1111");
			map.put("retMsg", "法人证件信息认证失败");
			logger.info("ERROR = 国政通校验身份信息不匹配");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证商户注册详细地址
	 * @param rgstaddress商户注册详细地址
	 * @return
	 */
	public static Map<String, String> registerAddress(String rgstaddress){
		logger.info("【开始验证商户注册详细地址】" + rgstaddress);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(rgstaddress) && !"null".equals(rgstaddress)) {
			if (rgstaddress.length() > 64) {
				logger.info("ERROR = 商户注册详细地址不能超过64个汉字");
				map.put("retCode", "1111");
				map.put("retMsg", "商户注册详细地址不能超过64个汉字");
				return map;
			}
		}else {
			logger.info("ERROR = 商户注册详细地址不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "商户注册详细地址不能为空");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证证书接收邮箱
	 * @param email证书接收邮箱
	 * @return
	 */
	public static Map<String, String> email(String email){
		logger.info("【开始验证证书接收邮箱】" + email);
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(email) && !"null".equals(email)) {
			if(!email.matches(EMAIL_REGEX)){
				logger.info("ERROR = 证书接收邮箱格式错误");
				map.put("retCode", "1111");
				map.put("retMsg", "证书接收邮箱格式错误");
				return map;
			}
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证银行账号
	 * @param payeeName收款人姓名
	 * @param payeeInidcard收款人证件号（加密）
	 * @param bankAccount银行卡号
	 * @param prestorePhone银行预留手机号
	 * @return
	 */
	public static Map<String, String> bankAccount(String payeeName, String payeeInidcard, String bankAccount, String prestorePhone){
		logger.info("【开始验证银行账号】" + "收款人姓名：" + payeeName + "收款人身份证号：" + payeeInidcard + "银行账号：" + bankAccount + "预留手机号：" + prestorePhone) ;
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isBlank(bankAccount) || "null".equals(bankAccount)) {
			logger.info("ERROR = 银行账号不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "银行账号不能为空");
			return map;
		}
		if (StringUtils.isBlank(prestorePhone) || "null".equals(prestorePhone)) {
			logger.info("ERROR = 银行预留手机号不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "银行预留手机号不能为空");
			return map;
		}
/*		
		//【1】先查询批量详情表
		com.umpay.operation.common.ReqMessage req1 = ReqMessageUtil.makeOpReq();
		com.umpay.operation.common.ResMessage res1 = null;
		req1.put("bankAccount",DesIDUtil.encID(bankAccount));
		req1.put("delFlag","0");// 是否删除 CHAR(1)  0:未删除；1:已删除
		try {
			logger.info("【四要素查询银行卡信息】入参" + req1);
			res1 = tStoreBatchDetailServiceRemote.queryBatchDetailList(req1);
			logger.info("【四要素查询银行卡信息】出参" + res1);
		} catch (Exception e) {
			logger.error("【四要素查询银行卡信息】异常", e);
		}
		if (res1 != null) {
			if (res1.getRetCode().equals("0000")) {
				List<StoreBatchDetail> storeBatchDetailList = (List<StoreBatchDetail>) res1.getResMap().get("storeBatchDetailList");
				if(storeBatchDetailList.size() > 0){
					for (StoreBatchDetail storeBatchDetail : storeBatchDetailList) {
						if (!prestorePhone.equals(storeBatchDetail.getPrestorePhone()) || !payeeName.equals(storeBatchDetail.getPayeeName()) || !DesIDUtil.encID(payeeInidcard).equals(storeBatchDetail.getPayeeInidcard())) {
							logger.info("ERROR = 银行卡四要素不一致");
							map.put("retCode", "1111");
							map.put("retMsg", "银行卡四要素不一致");
							return map;
						}
					}
					map.put("retCode", "0000");
					return map;
				}
			}
		}
*/		
		//【2】如果查询不到，再公共鉴权
		Map<String, Object> req = ReqMessageUtil.makeCrmMap();
		Map<String, Object> res = null;
		req.put("reqDate", DateUtil.getSystemDate("yyyyMMdd"));
		req.put("reqTime", DateUtil.getSystemDate("HHmmss"));
		req.put("merId",JQMERID);
		req.put("productId", "P15Y0002");//产品号传了立马付中的任意一个
		req.put("busiMerId", JQMERID);
		req.put("bankAccount", StringUtils.trim(DesIDUtil.encID(bankAccount)));
		req.put("accountName", payeeName);
		req.put("bankIdentityType", "1");
		req.put("bankIdentityCode", DesIDUtil.encID(payeeInidcard));//证件号密文
		req.put("bankMobileId", StringUtils.trim(prestorePhone));
		req.put("strictVeriFlag", "1");	//借记卡四要素强校验标识
		try {
			logger.info("【公共鉴权校验银行卡信息】入参" + req);
			res = HttpUtil.httpPostForm2Xml(ID_AUTH, req, "utf-8");
			logger.info("【公共鉴权校验银行卡信息】出参" + res);
		} catch (Exception e) {
			logger.error("【公共鉴权校验银行卡信息】异常", e);
			map.put("retCode", "1111");
			map.put("retMsg", "银行卡验证失败");
			return map;
		}
		if (res != null) {
			if (!res.get("retCode").equals("0000")) {
				logger.info("ERROR = 公共鉴权校验银行卡未通过");
				map.put("retCode", "1111");
				map.put("retMsg", "银行卡鉴权未通过");
				return map;
			}
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证标签一
	 * @param labelOne标签一
	 * @return
	 */
	public static Map<String, String> labelOne(String labelOne){
		logger.info("【开始验证标签一】" + labelOne) ;
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(labelOne) && !"null".equals(labelOne)) {
			if (labelOne.length() > 32) {
				logger.info("ERROR = 标签一不能超过32个汉字");
				map.put("retCode", "1111");
				map.put("retMsg", "标签一不能超过32个汉字");
				return map;
			}
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证标签二
	 * @param labelOne标签二
	 * @return
	 */
	public static Map<String, String> labelTwo(String labelTwo){
		logger.info("【开始验证标签二】" + labelTwo) ;
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(labelTwo) && !"null".equals(labelTwo)) {
			if (labelTwo.length() > 32) {
				logger.info("ERROR = 标签二不能超过32个汉字");
				map.put("retCode", "1111");
				map.put("retMsg", "标签二不能超过32个汉字");
				return map;
			}
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证立马付微信、支付宝费率
	 * 单位为%，例如：0.23
	 * @param agentId代理商编号
	 * @param wechatRate微信费率
	 * @param alipayRate支付宝费率
	 * @return
	 * @throws ParseException 
	 */
	public static Map<String, String> rate(String agentId, String wechatRate, String alipayRate) throws Exception{
		logger.info("【开始验证立马付微信、支付宝费率】" + "微信费率" + wechatRate + "支付宝费率" + alipayRate) ;
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isBlank(wechatRate) || StringUtils.isBlank(alipayRate) || "null".equals(wechatRate) || "null".equals(alipayRate)) {
			logger.info("ERROR = 费率不能为空");
			map.put("retCode", "1111");
			map.put("retMsg", "微信费率或支付宝费率不能为空");
			return map;
		}
		double wx = Double.valueOf(wechatRate);
		double ali = Double.valueOf(alipayRate);
		if (wx > 10 || ali > 10) {
			logger.info("ERROR = 费率不能大于10%");
			map.put("retCode", "1111");
			map.put("retMsg", "费率不能大于10%");
			return map;
		}
		
		//【1】校验联动给代理商设置的费率
		Map<String,Object> req = ReqMessageUtil.makeCrmMap();
		req.put("reqDate",DateUtil.getSystemDate("yyyyMMdd"));
		req.put("reqTime",DateUtil.getSystemDate("HHmmss"));
		Map<String,Object> res = null;
		req.put("agentId",agentId);
		req.put("type", AGENTPROFITTYPE);//定价产品 type就传 10，传0时有数据方便测试
		try {
			logger.info("【获取联动给代理商设置的费率】入参" + req + "【请求地址】" + AGENTPROFITURL);
			res = HttpUtil.httpPostForm2Xml(AGENTPROFITURL, req, "utf-8");
			logger.info("【获取联动给代理商设置的费率】出参" + res);
		} catch (Exception e) {
			logger.error("【获取联动给代理商设置的费率】异常", e);
			map.put("retCode", "1111");
			map.put("retMsg", "费率校验失败请重试");
			return map;
		}
		if (!res.get("retCode").equals("0000")) {
			map.put("retCode", "1111");
			map.put("retMsg", "费率校验失败请重试");
			return map;
		}
		double lowRateStander=200d;
		if (res.get("list") != null) {
			JSONArray json = JSONArray.fromObject(res.get("list"));
			List<SetAgentRateCfg> list =json.toList(json, SetAgentRateCfg.class);
			//循环查询到的费率，将最低值中的较大者取出来
			for (SetAgentRateCfg sa : list) {
				String sDate = sa.getStartDate();
				String eDate = sa.getEndDate();
				DateFormat df=new SimpleDateFormat("yyyyMMdd");
				long startDate = df.parse(sDate).getTime();
				long endDate = df.parse(eDate).getTime();
				long nowDate=new Date().getTime();
				if(startDate<=nowDate && nowDate<=endDate){
					if("25".equals(sa.getRuleValue())){
						double fratVal=Double.parseDouble((sa.getFratVal()));
						lowRateStander = fratVal * 100000;	//"fratVal": "0.001234"	
					}
				}
			}
		}
		logger.info("【联动给代理商设置的最低费率】" + lowRateStander/100000);
		
		//【2】查询代理商设置的立马付费率接口
		ReqMessage req1 = ReqMessageUtil.makeOpReq();
		ResMessage res1 = null;
		req1.put("agentId",agentId);
		try {
			logger.info("【查询代理商设置的费率】入参" + req1);
			res1 = ratesServiceRemote.getRatesByAgentId(req1);
			logger.info("【查询代理商设置的费率】出参" + res1);
		} catch (Exception e) {
			logger.error("【查询代理商设置的费率】异常", e);
			map.put("retCode", "1111");
			map.put("retMsg", "费率校验失败请重试");
			return map;
		}
		if (!res1.getRetCode().equals("0000")) {
			logger.info("【查询代理商设置的费率】失败");
			map.put("retCode", "1111");
			map.put("retMsg", "费率校验失败请重试");
			return map;
		}
		Map<String, Object> resMap = res1.getResMap();
		RatesConf ratesConf = (RatesConf) resMap.get("ratesConf");
		if (ratesConf == null) {
			logger.info("【查询代理商设置的费率】没有查询到代理商上配置的费率信息");
			map.put("retCode", "1111");
			map.put("retMsg", "费率校验失败请重试");
			return map;
		}
		double highRate = Double.valueOf(ratesConf.getHighRate());
		double lowRate = Double.valueOf(ratesConf.getHighRate());
		if (wx < lowRate || wx > highRate || wx < lowRateStander/1000) {
			logger.info("ERROR = 设置的微信费率不在有效范围内");
			map.put("retCode", "1111");
			map.put("retMsg", "费率必须在" + lowRate + "~" + highRate + "之间，且大于等于" + lowRateStander/1000);
			return map;
		}
		if (ali < lowRate || ali > highRate || ali < lowRateStander/1000) {
			logger.info("ERROR = 设置的支付宝费率不在有效范围内");
			map.put("retCode", "1111");
			map.put("retMsg", "费率必须在" + lowRate + "~" + highRate + "之间，且大于等于" + lowRateStander/1000);
			return map;
		}

		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证固码1
	 * @param code固码
	 * @return
	 */
	public static Map<String, String> codeOne(String codeOne){
		logger.info("【开始验证固码1】" + codeOne) ;
		Map<String, String> map = new HashMap<String, String>();
		map = code(codeOne);
		if (map.get("retCode").equals("0001")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码1格式错误");
			return map;
		}
		if (map.get("retCode").equals("0002")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码1校验失败，请重试");
			return map;
		}if (map.get("retCode").equals("0003")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码1无效");
			return map;
		}
		if (map.get("retCode").equals("0004")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码1已被其它商户绑定");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证固码2
	 * @param code固码
	 * @return
	 */
	public static Map<String, String> codeTwo(String codeTwo){
		logger.info("【开始验证固码2】" + codeTwo) ;
		Map<String, String> map = new HashMap<String, String>();
		map = code(codeTwo);
		if (map.get("retCode").equals("0001")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码2格式错误");
			return map;
		}
		if (map.get("retCode").equals("0002")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码2校验失败，请重试");
			return map;
		}if (map.get("retCode").equals("0003")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码2无效");
			return map;
		}
		if (map.get("retCode").equals("0004")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码2已被其它商户绑定");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证固码3
	 * @param code固码
	 * @return
	 */
	public static Map<String, String> codeThree(String codeThree){
		logger.info("【开始验证固码3】" + codeThree) ;
		Map<String, String> map = new HashMap<String, String>();
		map = code(codeThree);
		if (map.get("retCode").equals("0001")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码3格式错误");
			return map;
		}
		if (map.get("retCode").equals("0002")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码3校验失败，请重试");
			return map;
		}if (map.get("retCode").equals("0003")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码3无效");
			return map;
		}
		if (map.get("retCode").equals("0004")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码3已被其它商户绑定");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证固码4
	 * @param code固码
	 * @return
	 */
	public static Map<String, String> codeFour(String codeFour){
		logger.info("【开始验证固码4】" + codeFour) ;
		Map<String, String> map = new HashMap<String, String>();
		map = code(codeFour);
		if (map.get("retCode").equals("0001")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码4格式错误");
			return map;
		}
		if (map.get("retCode").equals("0002")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码4校验失败，请重试");
			return map;
		}if (map.get("retCode").equals("0003")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码4无效");
			return map;
		}
		if (map.get("retCode").equals("0004")) {
			map.put("retCode", "1111");
			map.put("retMsg", "固码4已被其它商户绑定");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证固码公共部分
	 * @param code固码
	 * @return
	 */
	public static Map<String, String> code(String code){
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isBlank(code) || "null".equals(code)) {
			map.put("retCode", "0000");
			return map;
		}
		if (!NUM3_PATTERN.matcher(code).matches()) {
			logger.info("ERROR = 固码格式错误");
			map.put("retCode", "0001");
			return map;
		}
		com.umpay.operation.common.ReqMessage req = ReqMessageUtil.makeOpReq();
		com.umpay.operation.common.ResMessage res = null;
		req.put("qrId",code);
		try {
			logger.info("【查询收款码】入参" + req);
			res = qrConfServiceRemote.queryQrConfByKey(req);
			logger.info("【查询收款码】出参" + res);
		} catch (Exception e) {
			logger.error("【查询收款码】异常", e);
			map.put("retCode", "0002");
			return map;
		}
		if (!"0000".equals(res.getRetCode())) {
			logger.info("【查询收款码】失败，该固码无效");
			map.put("retCode", "0003");
			return map;
		}
		QrConf qrConf = (QrConf) res.getValue("qrConf");
		if (null != qrConf.getMerId() && !"".equals(qrConf.getMerId())) {
			logger.info("【查询收款码】失败，该固码已被其它商户绑定");
			map.put("retCode", "0004");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
	
	/**
	 * 验证店铺简称是否重名
	 * @param storeShortName店铺简称
	 * @param merId主商户号
	 * @return
	 */
	public static Map<String, String> storeShortSame(String storeShortName, String merId){
		logger.info("【开始验证店铺简称是否重名】" + "主商户号：" + merId + "简称：" + storeShortName) ;
		Map<String, String> map = new HashMap<String, String>();
		ReqMessage req = ReqMessageUtil.makeOpReq();
		ResMessage res = null;
		req.put("storeShortName",storeShortName);
		req.put("merId",merId);
		try {
			logger.info("【查询商户简称是否已存在】入参" + req);
			res = storeInfServiceRemote.countStoreInfByStoreNameAndMerId(req);
			logger.info("【查询商户简称是否已存在】出参" + res);
		} catch (Exception e) {
			logger.error("【查询商户简称是否已存在】异常", e);
			map.put("retCode", "1111");
			map.put("retMsg", "校验商户简称失败，请重试");
			return map;
		}
		if (!res.getRetCode().equals("0000")) {
			map.put("retCode", "1111");
			map.put("retMsg", "校验商户简称失败，请重试");
			return map;
		}
		Integer storeCount = (Integer) res.getResMap().get("storeCount");
		if (storeCount > 0) {
			map.put("retCode", "1111");
			map.put("retMsg", "商户简称已存在");
			return map;
		}
		map.put("retCode", "0000");
		return map;
	}
}
 